package com.jlanglang.glide.loaderdemo.util

import java.io.ByteArrayInputStream
import java.io.InputStream
import java.security.SecureRandom
import javax.crypto.Cipher
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.DESKeySpec

class DESUtil {
    companion object {
        private const val ALGORITHM_DES = "DES"
        /**
         * 加密二进制数组
         * @param byteArray 需要加密的二进制
         * @param pwd 加密的Key,长度为8和8的倍数
         */
        fun encode(byteArray: ByteArray?, pwd: String): ByteArray? {
            if (pwd.isEmpty()) {
                return byteArray
            }
            return try {
                val sr = SecureRandom()
                val dks = DESKeySpec(pwd.toByteArray(charset("utf-8")))
                val keyFactory = SecretKeyFactory.getInstance("DES")
                // key的长度不能够小于8位字节
                val secretKey = keyFactory.generateSecret(dks)
                val cipher = Cipher.getInstance(ALGORITHM_DES)
                cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr)
                val bytes = cipher.doFinal(byteArray)
                bytes
            } catch (e: Exception) {
                null
            }
        }
        /**
         * 解密二进制数组
         * @param byteArray 需要解密密的二进制
         * @param pwd 加密的Key,长度为8和8的倍数
         */
        fun decode(byteArray: ByteArray?, pwd: String): ByteArray? {
            if (pwd.isEmpty()) {
                return byteArray
            }
            return try {
                val sr = SecureRandom()
                val dks = DESKeySpec(pwd.toByteArray(charset("utf-8")))
                val keyFactory = SecretKeyFactory.getInstance("DES")
                val secretKey = keyFactory.generateSecret(dks)
                val cipher = Cipher.getInstance(ALGORITHM_DES)
                cipher.init(Cipher.DECRYPT_MODE, secretKey, sr)
                cipher.doFinal(byteArray)
            } catch (e: Exception) {
                null
            }
        }

        /**
         * 解密输入流
         */
        fun decodeInputStream(inputStream: InputStream?, pwd: String): InputStream? {
            return inputStream?.apply {
                val decode =
                    decode(
                        readBytes(),
                        pwd
                    )
                return ByteArrayInputStream(decode)
            }
        }
    }
}